# gozerbot/gozernet/event.py
#
#

""" gozernet remote event. """

## gozerlib imports

from gozerbot.eventbase import EventBase
from gozerbot.utils.generic import splittxt
from gozerbot.utils.log import rlog

## basic imports

import cgi
import logging
import copy
import types

from xml.sax.saxutils import escape 

cpy = copy.deepcopy

class RemoteEvent(EventBase):

    def __init__(self): 
        EventBase.__init__(self)
        self.type = "remote"

    def __deepcopy__(self, a):
        e = EventBase()
        e.copyin(self)
        return e

    def parse(self, bot, eventin):

        """ parse request/response into a RemoteEvent. """

        #rlog(10, 'gozernet', eventin)
        self.fromjsonstring(eventin.txt)
        self.isremote = True
        self.bot = bot
        rlog(10, 'gozernet', 'in - %s - %s - %s' % (self.userhost, self.txt, self.cbtype))
        return self

    def _raw(self, txt, end=""):
    
        """
            put txt onto the reponse object .. adding end string if provided. 
            output is NOT escaped.
    
        """

        rlog(10, 'gozernet', 'out - %s - %s' % (self.remoteout, txt))
        self.bot.say(self.remoteout, txt, self)

    def write(self, txt, start=u"", end=u"<br>", raw=True):

        """ 
            put txt onto the reponse object .. adding end string if provided. 
            output IS escaped.

        """
         
        if not raw:
            self._raw(start + escape(txt) + end)
        else:
            self._raw(start + txt + end)

    def reply(self, txt, resultlist=[], nritems=False, dot=" .. ", raw=False, *args, **kwargs):

        """ send reply to the web user. """

        if self.checkqueues(resultlist):
            return

        result = self.makeresponse(txt, resultlist, nritems, dot, *args, **kwargs)
        self.write(result)

    def missing(self, txt):

        """ 
            display missing arguments. 

            :param txt: txt to display
            :type txt: string
            :rtype: None

        """

        if self.origtxt:
            splitted = self.origtxt.split()

            if self.bot.nick in splitted[0]:

                try:
                    cmnd = splitted[1]
                except IndexError:
                    cmnd = splitted[0]

            elif 'cmnd' in splitted[0]:

                try:
                    cmnd = splitted[2]
                except IndexError:
                    cmnd = splitted[0]

            else:

                if self.msg:
                    cmnd = splitted[0]
                else:
                    if self.aliased:
                        cmnd = self.aliased
                    else:
                        cmnd = splitted[0]

            self.reply(cmnd + ' ' + txt)

        else:
            self.reply('missing origtxt: %s' % txt)

    def checkqueues(self, resultlist):

        """ 
            check if resultlist is to be sent to the queues. if so do it

            :param resultlist: list of results to send to queues
            :type resultlist: list
            :rtype: boolean

        """

        if self.queues:

            for queue in self.queues:
                for item in resultlist:
                    queue.put_nowait(item)

            return True

        return False

    def done(self):

        """ tell the user we are done. """

        self.reply('done')


    def less(self, what, raw=False):
        """
            split up in parts of 1000 chars overflowing on word boundaries.
            put remaining txt into outcache.

            :param what: text to split
            :type what: string
            :rtype: list of 1st and second string to display

        """
        what = what.strip()
        txtlist = splittxt(what, 1000)
        size = 0

        # send first block
        res = txtlist[0]

        # see if we need to store output in less cache
        result = ""
        if len(txtlist) > 2:
            self.bot.outcache.add(self.userhost, txtlist[1:])
            size = len(txtlist) - 2
            result = txtlist[1:2][0]
            if size:
                result += " (+%s)" % size
        else:
            if len(txtlist) == 2:
                result = txtlist[1]

        return [res, result]

    def makeargs(self):

        """ make arguments and rest attributes from self.txt. """

        try:
            self.args = self.txt.split()[1:]
            self.rest = ' '.join(self.args)
        except:
            self.args = None

    def makeresponse(self, txt, result=[], nritems=False, dot=" .. ", *args, **kwargs):

        """ 
            create response. 

            :param txt: text prepended to result
            :type txt: string
            :param result:
            :type result: list of results (strings)
            :param nritems: whether items should be numbered (not used now)
            :type nritems: boolean
            :rtype: string

        """

        res = unicode(txt) 

        if result:


            if dot == True:
                dot = " .. "
               
            if type(result) == types.DictType:
                res += str(result) + ' .. '
            else:
                counter = 1

                for item in result:

                    if nritems:
                        res += str(counter) + u') ' + unicode(item)
                    else:
                        res += unicode(item)

                    if dot:
                        res += dot
                    else:
                        res += u' '

                    counter += 1

            if dot:
                res = res[:-len(dot)]
          
        return res
